package com.cloud.product.service.impl;

import com.cloud.dto.CartDto;
import com.cloud.input.ProductInfoOutput;
import com.cloud.product.entity.ProductInfo;
import com.cloud.product.enums.ProductStatus;
import com.cloud.product.exception.ProductException;
import com.cloud.product.repository.ProductInfoRepository;
import com.cloud.product.service.ProductServiceInf;
import com.google.gson.Gson;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * describe:
 *
 * @author zhanghaixuan
 * @date 2018/09/10
 **/
@Service
public class ProductServiceImpl implements ProductServiceInf {

	@Autowired
	private AmqpTemplate amqpTemplate;

    @Autowired
    private ProductInfoRepository productInfoRepository;

    @Override
    public List<ProductInfo> findUpProductInfo() {
        return productInfoRepository.findByProductStatusIs(ProductStatus.UP.getCode());
    }

    @Override
    public List<ProductInfoOutput> findProductByIds(List<String> productLists) {
        List<ProductInfo> byProductIdIn = productInfoRepository.findByProductIdIn(productLists);

        List<ProductInfoOutput> returnList = byProductIdIn.stream()
                .map(e ->{
                    ProductInfoOutput productInfoOutput = new ProductInfoOutput();
                    BeanUtils.copyProperties(e,productInfoOutput);
                    return productInfoOutput;
                } )
                .collect(Collectors.toList());


        return returnList;
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void decreaseStock(List<CartDto> cartDtos) {
		List<ProductInfo> productInfos = decreaseStockProcess(cartDtos);
		List<ProductInfoOutput> productInfoOutputs = new ArrayList<>();

		for(ProductInfo productInfo : productInfos) {
			ProductInfoOutput productInfoOutput = new ProductInfoOutput();
			BeanUtils.copyProperties(productInfo,productInfoOutput);
			/**
			 * 发送消息
			 */

			productInfoOutputs.add(productInfoOutput);
		}
		Gson gson = new Gson();
		amqpTemplate.convertAndSend("productInfo",gson.toJson(productInfoOutputs));
	}


    @Transactional(rollbackFor = Exception.class)
    public List<ProductInfo> decreaseStockProcess(List<CartDto> cartDtos) {
        /**
         *  update product set srock = stock - aaa  where stock - aaa>0
         */
		List<ProductInfo> productInfos =  new ArrayList<>();

        for (CartDto cartDto : cartDtos) {
            /**
             * springjpa 2.0 抛弃了 find one 方法  使用  findbyid 返回类型也做了改变: 变成了 OPtional<T>
             */
            Optional<ProductInfo> byId = productInfoRepository.findById(cartDto.getProductId());
            /**
             * 判断商品是否存在
             */
            if(!byId.isPresent()){
                throw new ProductException("商品不存在!");
            }

            ProductInfo productInfo = byId.get();
            Integer result = productInfo.getProductStock()  - cartDto.getProductQuantity()  ;
            /**
             * 判断是否足够扣库存
             */
            if(result<0){
                throw new ProductException(productInfo.getProductName()+"库存不够!");
            }

            productInfo.setProductStock(result);

            productInfoRepository.save(productInfo);

			productInfos.add(productInfo);
        }

        return productInfos;
    }
}
